//xlang Source, Name:BusinessSrv.x 
//Date: Mon Apr 02:53:07 2024 

class BusinessSrv: AsyncInput{
    Server _server = new Server(this);
	Unsi _unsi = new Unsi();

    static int proxy_serverPort, proxy_proxyPort, timeout = 90000, buffersize = 4096, thread = 2;
    static String key;
    
    public static String getKey(){
        return key;
    }
    
    public static bool loadConfigure(){
        FileStream.FileInputStream fis = nilptr;
        try{
            File fp = new File(_system_.getAppDirectory().appendPath("proxy_server.json"));
            if (fp.exists()){
                fis =  new FileStream.FileInputStream(fp);
                JsonObject json = new JsonObject(new String(fis.read()));
                
                proxy_serverPort = json.getInt("proxy_serverPort");
                proxy_proxyPort = json.getInt("proxy_proxyPort");
                key = json.getString("key");
                
                if (json.has("timeout")){
                    timeout = json.getInt("timeout");
                }
                if (json.has("buffersize")){
                    buffersize = json.getInt("buffersize");
                }
                if (buffersize < 1024){
                    buffersize = 1024;
                }
                if (json.has("thread")){
                    thread = json.getInt("thread");
                }
                if (thread < 1){
                    thread = 1;
                }
                return proxy_serverPort != 0 && proxy_proxyPort != 0;
            }
        }catch(Exception e){
        
        }finally{
            if (fis != nilptr){
                fis.close();
            }
        }
        return false;
    }
    
    Map<int, long> ctx_map = new Map<int, long>();
     
    public bool create(){
		if (_unsi.create(this, 1, proxy_proxyPort, timeout) == false){
			//System.out.print("创建服务器失败\n");
            return false;
		}
        
        _unsi.config(thread, buffersize, timeout);
        
        if (_unsi.start() == false){
			//System.out.print("开启服务器失败\n");
		}else{
            if (_server.create(proxy_serverPort)){
                return true;
            }
		}
        return false;
    }
    
	void notify(AsyncOutput output, int type, long bind, bool bsucceed, long context,int length)override{

	}


	bool newInstance(AsyncOutput output, int type, long bind, long context)override{
        if (_server.isValid()){
            int id = output.getInstanceId(context);
            _server.newConnect(id);
            synchronized (ctx_map) {
                ctx_map.put(id,output.cloneContext(context));    
            }
            return true;
        }
		return false;
	}

	bool dataArrives(AsyncOutput output, long context, byte[] data, int offset, int length)override{
        int sid = output.getInstanceId(context);
        _server.write(sid, data, offset, length);
		return true;
	}

	bool deleteInstance(AsyncOutput output, long context)override{
        long _s_id = 0;
        int id = output.getInstanceId(context);
        
        synchronized (ctx_map) {
            var iter = ctx_map.find(id);    
            if (iter != nilptr){
                _s_id = iter.getValue();
                ctx_map.remove(iter);
            }
        }
        
        if (_s_id != 0){
            _server.onClose(id);
            _unsi.getAsyncDirectOutput().releaseContext(_s_id);
        }
        
		return true;
	}

	bool inactiveTimeout(AsyncOutput output, long context)override{
		return false;
	}
    
    public void onrecv(int id, byte [] data, int offset, int length){
        long _s_id = 0;
        
        synchronized (ctx_map) {
            var iter = ctx_map.find(id);    
            if (iter != nilptr){
                _s_id = iter.getValue();
            }
        }
        
        if (_s_id != 0){
            _unsi.getAsyncDirectOutput().dataDeparture(this, _s_id,0,data,offset,length);
        }
    }
    
    public void onSVNClose(int id){ // 客户端断开了 
        long _s_id = 0;
        
        synchronized (ctx_map) {
            var iter = ctx_map.find(id);    
            if (iter != nilptr){
                _s_id = iter.getValue();
                ctx_map.remove(iter);
            }
        }
        
        if (_s_id != 0){    // 如果有关联 关闭关联 释放句柄
            _unsi.getAsyncDirectOutput().deleteInstance(this, _s_id);
            _unsi.getAsyncDirectOutput().releaseContext(_s_id);
        }
    }
};